package com.itrus.spring.mvc;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author peigen
 * @since 2024/10/8
 *
 * <a href="https://www.rfc-editor.org/rfc/rfc9110.html#fields"> rfc9110 </a>
 * 1. http header 不区分大小写
 * 2. http header 值重复出现时，应合并 value
 * <p>
 * spring 解析 header 源码实现：
 * RequestHeaderMethodArgumentResolver#resolveArgument
 * RequestHeaderMapMethodArgumentResolver#resolveArgument
 * <p>
 * 建议：
 * 1. 单个 header 获取，使用 @RequestHeader("headerName") 方式获取 header
 * 2. 多个 header 获取，使用 @RequestHeader HttpHeaders headers 方式获取
 */
@Slf4j
@RestController
public class HeaderController {

    /**
     * curl "http://localhost:8080/header" --header "test: a" --header "test: b"
     */
    @RequestMapping("/header")
    public String header(@RequestHeader("test") String test) {
        return test;
    }

    /**
     * curl "http://localhost:8080/header/map" --header "test: a" --header "test: b"
     */
    @RequestMapping("/header/map")
    public String map(@RequestHeader Map<String, String> map) {
        return JSON.toJSONString(map);
    }


    /**
     * curl "http://localhost:8080/header/multiMap" --header "test: a" --header "test: b"
     */
    @RequestMapping("/header/multiMap")
    public String map(@RequestHeader MultiValueMap<String, String> map) {
        return JSON.toJSONString(map);
    }

    /**
     * 推荐使用
     * curl "http://localhost:8080/header/httpHeaders" --header "test: a" --header "test: b"
     */
    @RequestMapping("/header/httpHeaders")
    public String map(@RequestHeader HttpHeaders headers) {
        headers.get("a");
        return JSON.toJSONString(headers);
    }

    /**
     * curl "http://localhost:8080/header/ignoreCase" --header "test: a"
     */
    @RequestMapping("/header/ignoreCase")
    public String ignoreCase(HttpServletRequest request, @RequestHeader Map<String, String> map) {
        String request1 = request.getHeader("test");
        String request2 = request.getHeader("tEst");

        String map1 = map.get("test");
        String map2 = map.get("tEst");

        log.info("request1=" + request1);
        log.info("request2=" + request2);
        log.info("map1=" + map1);
        log.info("map2=" + map2);

        return JSON.toJSONString(map);
    }
}
